using System;
using System.Linq;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Runtime.InteropServices;


namespace LightCAD.Three
{
    public class EventArgs
    {
        public string type;
        public object target;
        public object data;
        public JsObj<object> args;
        public object mode;
        public object value;
        public EventArgs()
        {
            this.args = new JsObj<object>();
        }
        public EventArgs(object target, string type)
        {
            this.target = target;
            this.type = type;
            this.args = new JsObj<object>();
        }

    }
    public delegate void EventHandler(EventArgs e);
    public class EventDispatcher
    {
        private Dictionary<string, List<EventHandler>> _listeners;


        public void addEventListener(string type, EventHandler listener)
        {

            if (this._listeners == null) this._listeners = new Dictionary<string, List<EventHandler>>();

            var listeners = this._listeners;


            if (!listeners.ContainsKey(type))
            {
                listeners.Add(type, new List<EventHandler>());
            }

            if (listeners[type].IndexOf(listener) == -1)
            {
                listeners[type].Add(listener);

            }

        }

        public bool hasEventListener(string type, EventHandler listener)
        {

            if (this._listeners == null) this._listeners = new Dictionary<string, List<EventHandler>>();

            var listeners = this._listeners;

            var existType = listeners.ContainsKey(type);
            if (!existType) return false;
            return listeners[type].IndexOf(listener) >= 0;
        }

        public void removeEventListener(string type, EventHandler listener)
        {

            if (this._listeners == null) return;

            var listeners = this._listeners;
            List<EventHandler> listenerArray;
            listeners.TryGetValue(type, out listenerArray);

            if (listenerArray != null)
            {

                var index = listenerArray.IndexOf(listener);

                if (index != -1)
                {

                    listenerArray.RemoveAt(index);

                }

            }

        }

        public void dispatchEvent(EventArgs e)
        {

            if (this._listeners == null) return;

            var listeners = this._listeners;
            List<EventHandler> listenerArray;
            listeners.TryGetValue(e.type, out listenerArray);

            if (listenerArray != null)
            {


                e.target = this;

                var array = listenerArray.ToArray();

                for (int i = 0, l = array.Length; i < l; i++)
                {

                    array[i](e);

                }

            }

        }
    }

}